/*!
 * \file SgwGapProxy.h
 * \brief Proxy for communication with Serving Gateway via GAP protocol
 */

#ifndef MGW_SERVING_GATEWAY_GAP_PROXY_H
#define MGW_SERVING_GATEWAY_GAP_PROXY_H

#include <string>
#include <map>
#include "GapGenerator.h"
#include "RequestHandler.h"
#include "Message.h"

namespace tsc
{
namespace mgw
{

using namespace GatewayApplicationPart;

/**
 * Proxy for communication with Serving Gateway via GAP protocol
 */
class SgwGapProxy
{
public:

	/**
	 * Returns singleton instance of the proxy
	 */
	static SgwGapProxy& instance();

	static void init(common::RequestHandler* rh);

	void handlePdu(common::Message*& msg);

	bool sendGapConnectionInd(GapGenerator& gapGen);

	bool sendGapEchoResp(GapGenerator& gapGen);

	bool sendGapMediaBearerSetupCfm(GapGenerator& gapGen,
	                                uint32_t connectionId,
	                                uint32_t serverMediaPort);

	bool sendGapMediaBearerSetupRej(GapGenerator& gapGen,
	                                uint32_t connectionId,
	                                GatewayApplicationPart::Cause cause);

	bool sendGapTransmissionFinishedInd(GapGenerator& gapGen,
	                                    uint32_t connectionId);

	common::RequestHandler* getRequestHandler();
private:

	/**
     * Handle GapPdu received from Serving Gateway
     *
     * \param gapPdu the pdu to handle
     */
    void handleGapPdu(GatewayApplicationPart::GapPdu*& gapPdu);

    /**
     * Sends the provided encoded GAP message to the Serving Gateway
     *
     * \param mgwId ID of MGW
     * \param msg encoded GAP message to send
     * \param pduNum GapPduNumber of the message to send
     * \return <code>true</code> on success, <code>false</code> otherwise
     */
    bool sendGapPdu(uint32_t                             mgwId,
                    const std::string&                   msg,
                    GatewayApplicationPart::GapPduNumber pduNum);

    SgwGapProxy(common::RequestHandler* rh);

	~SgwGapProxy();

	static SgwGapProxy* mInstance;
	common::RequestHandler* mpReqHandler;
};

} // namespace mgw
} // namespace tsc

#endif // MGW_SERVING_GATEWAY_GAP_PROXY_H
